﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Abp.AutoMapper;
using System.Linq.Dynamic;
using Abp.Linq.Extensions;
using System.Threading.Tasks;
using MyCompanyName.AbpZeroTemplate.Prm.Authorization;
using MyCompanyName.AbpZeroTemplate.Prm.Search.Dto;
using MyCompanyName.AbpZeroTemplate.Prm.Project;
using MyCompanyName.AbpZeroTemplate.Prm.Admin;
using Abp.Domain.Repositories;
using Abp.Application.Services.Dto;
using MyCompanyName.AbpZeroTemplate.Prm.Project.Dto;

namespace MyCompanyName.AbpZeroTemplate.Prm.Search
{
    public class SearchAppService : AbpZeroTemplateAppServiceBase, ISearchAppService
    {
        private readonly ProjectManager _projectManager;
        private readonly SubstanceManager _substanceManager;
        private readonly PermissionService _permissionService;
        private readonly IRepository<DocumentType, int> _documentTypeRepository;


        public SearchAppService(ProjectManager projectManager, PermissionService permissionService, SubstanceManager substanceManager, IRepository<DocumentType, int> documentTypeRepository)
        {
            _projectManager = projectManager;
            _substanceManager = substanceManager;
            _documentTypeRepository = documentTypeRepository;
            _permissionService = permissionService;
        }
        public PagedResultOutput<Project.Dto.ProjectOutPut> GetProject(Search.Dto.GetProjectInPut input)
        {
            var userId = (long)AbpSession.UserId;
            var projects = _projectManager.projectRepository.GetAll()
                .WhereIf(!string.IsNullOrEmpty(input.ProjectName), x => x.ProjectName.Contains(input.ProjectName))
                .WhereIf(!string.IsNullOrEmpty(input.ProductNo), x => x.ProductNo.Contains(input.ProductNo))
                .WhereIf(!string.IsNullOrEmpty(input.ProjectNo), x => x.ProjectNo.Contains(input.ProjectNo))
                .WhereIf(!string.IsNullOrEmpty(input.Customer), x => x.Customer.Contains(input.Customer))
                .WhereIf(!string.IsNullOrEmpty(input.CustomerCode), x => x.CustomeCode.Contains(input.CustomerCode))
                .WhereIf(input.BusinessId > 0, x => x.BusinessId == input.BusinessId)
                .WhereIf(input.RdCenterId > 0, x => x.RdCenterId == input.RdCenterId)
                .WhereIf(input.LaboratoryId > 0, x => x.LaboratoryId == input.LaboratoryId)
                .OrderBy(input.Sorting)
                .ToList()
                .Where(x => _permissionService.HasPermission(userId, x.Id, ProjectFunctions.项目查看));

            int total = projects.Count();
            var cc = projects.Skip(input.start).Take(input.limit).ToList();


            var projectListDtos = cc.MapTo<List<Project.Dto.ProjectOutPut>>();

            bool permissionToViewCustomer = _permissionService.HasSysPermission(userId, ProjectFunctions.客户查看);
            if (!permissionToViewCustomer)
            {
                foreach (var item in projectListDtos)
                {
                    item.Customer = "******";
                }
            }

            return new PagedResultOutput<ProjectOutPut>(total, projectListDtos);
        }


        public PagedResultOutput<GetSubstanceOutPut> GetSubstance(GetSubstanceInPut input)
        {
            List<string> cas = new List<string>();
            List<string> cnName = new List<string>();
            List<string> enName = new List<string>();
            List<string> formula = new List<string>();
            if (!string.IsNullOrEmpty(input.Cas))
            {
                cas = input.Cas.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            }
            if (!string.IsNullOrEmpty(input.CnName))
            {
                cnName = input.CnName.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            }
            if (!string.IsNullOrEmpty(input.EnName))
            {
                enName = input.EnName.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            }
            if (!string.IsNullOrEmpty(input.Formula))
            {
                formula = input.Formula.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            }
            var query = _substanceManager.Query(cas, cnName, enName, formula);
            var sublistdtos = new List<GetSubstanceOutPut>();
            var total = query.Count();
            var cc = query.Skip(input.start).Take(input.limit).ToList();
            foreach (Abp.Mtrl.Material item in cc)
            {
                sublistdtos.Add(new GetSubstanceOutPut()
                {
                    CAS = item.CASNo,
                    // CDX = item.CdxFile != null ? System.Text.Encoding.Default.GetString(item.CdxFile) : string.Empty,
                    // ChemDrawName = string.Empty,
                    CnName = item.CnName,
                    EnName = item.EnName,
                    Formula = item.MolecularFormula,
                    HighRisk = item.RiskStatements,
                    // Id = item.Id,
                    // MOL = item.MolString,
                    MolecularWeight = item.MolecularWeight,
                    MolPngBase64 = item.ImgFile != null ? Convert.ToBase64String(item.ImgFile) : string.Empty,
                    Note = string.Empty,
                    // Products = null

                });
            }


            return new PagedResultOutput<GetSubstanceOutPut>(total, sublistdtos);
        }


        public PagedResultOutput<GetDocumentOutPut> GetDocument(GetDocumentInPut input)
        {
            var query = _projectManager.projectDocmeutRepository.GetAll();
            if (!string.IsNullOrEmpty(input.ProjectName))
            {
                var pid = _projectManager.projectRepository.GetAll().Where(x => x.ProjectName.Contains(input.ProjectName)).Select(x => x.Id);
                query = query.Where(x => pid.Contains(x.ProjectId));
            }
            if (!string.IsNullOrEmpty(input.ProjectCode))
            {
                var pid = _projectManager.projectRepository.GetAll().Where(x => x.ProjectNo.Contains(input.ProjectCode)).Select(x => x.Id);
                query = query.Where(x => pid.Contains(x.ProjectId));
            }
            query = query.WhereIf(!string.IsNullOrEmpty(input.Name), x => x.Name.Contains(input.Name));

            var total = query.Count();

            var docs = query.OrderByDescending(x => x.ReportDate).ThenByDescending(x => x.Id).Skip(input.start).Take(input.limit).ToList();
            List<GetDocumentOutPut> result = new List<GetDocumentOutPut>();

            Dictionary<int, ProjectInfo> dicPro = new Dictionary<int, ProjectInfo>();
            Dictionary<int, string> dicDocType = new Dictionary<int, string>();

            foreach (var item in docs)
            {
                if (!dicPro.ContainsKey(item.ProjectId))
                {
                    dicPro.Add(item.ProjectId, _projectManager.projectRepository.Get(item.ProjectId));
                }
                if (!dicDocType.ContainsKey(item.DocTypeId))
                {
                    if (item.DocTypeId == 0)
                    {
                        dicDocType.Add(item.DocTypeId, "");
                    }
                    else
                    {

                        var docType = _documentTypeRepository.Get(item.DocTypeId);
                        dicDocType.Add(item.DocTypeId, docType.Name);
                    }
                }

                var project = dicPro[item.ProjectId];
                var outPut = new GetDocumentOutPut()
                {
                    Extension = item.Extension,
                    Length = item.Length.ToString(),
                    Name = item.Name,
                    Note = item.Note,
                    ReportDate = item.ReportDate.ToString("yyyy-MM-dd"),
                    VersionNo = item.VersionNo.ToString(),
                    ProjectName = project.ProjectName,
                    DocType = dicDocType[item.DocTypeId]
                };
                result.Add(outPut);
            }
            return new PagedResultOutput<GetDocumentOutPut>(total, result);
        }
    }
}
